PUT(code, 0, (uint32_t)(char_lists_size >> 1));
code += LINK_SIZE;
-#if defined PCRE2_DEBUG || defined SUPPORT_VALGRIND
+ /* If we added padding to align the list, initialize the bytes to
+ defined values, so the library is valgrind-clean. It could also
+ be a security concern for clients calling into PCRE2 via bindings
+ from a memory-safe language, if pcre2_serialize_encode() exposes
+ uninitialized memory that may contain sensitive information. */
+
if ((char_lists_size & 0x2) != 0)
- {
- /* In debug the unused 16 bit value is set
- to a fixed value and marked unused. */
- ((uint16_t*)data)[-1] = 0x5555;
-#ifdef SUPPORT_VALGRIND
- VALGRIND_MAKE_MEM_NOACCESS(data - 2, 2);
-#endif
- }
-#endif
+ ((uint16_t*)data)[-1] = 0xdead;
cb->char_lists_size =
CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t));
PCRE2_SIZE patlen;
PCRE2_SIZE valgrind_access_length;
PCRE2_SIZE erroroffset;
+int32_t serialize_rc;
+void *serialize_code;
+uint8_t *serialized_bytes;
+PCRE2_SIZE serialized_size;
/* The perltest.sh script supports only / as a delimiter. */
rc = show_pattern_info();
if (rc != PR_OK) return rc;
+/* Verify that the compiled structure can be serialized without generating
+memory errors. */
+
+serialize_code = PTR(compiled_code);
+PCRE2_SERIALIZE_ENCODE(serialize_rc, &serialize_code, 1, &serialized_bytes,
+ &serialized_size, general_context);
+if (serialize_rc != 1)
+ {
+ fprintf(outfile, "** pcre2_serialize_encode() returned %d instead of 1\n",
+ serialize_rc);
+ return PR_ABEND;
+ }
+
+#if defined SUPPORT_VALGRIND
+if (VALGRIND_CHECK_MEM_IS_DEFINED(serialized_bytes, serialized_size) != 0)
+ {
+ fprintf(outfile, "** pcre2_serialize_encode() returned undefined data\n");
+ return PR_ABEND;
+ }
+#endif
+
+PCRE2_SERIALIZE_FREE(serialized_bytes);
+
/* The "push" control requests that the compiled pattern be remembered on a
stack. This is mainly for testing the serialization functionality. */